jQuery has two methods for inserting elements before other elements: .insertBefore() and .before(). These two methods have the same function; their difference lies only in how they are chained to other methods. Another two methods, .insertAfter() and .after(), bear the same relationship with each other, but as their names suggest, they insert elements after other elements. For the back to top links we'll use the .insertAfter() method:
$(document).ready(function() {
$('<a href="#top">back to top</a>')
.insertAfter('div.chapter p');
$('<a id="top"></a>');
});
The .after() method would accomplish the same thing as .insertAfter(), but with the selector expression preceding the method rather than following it. Using .after(), the first line inside $(document).ready() would look like this:
$('div.chapter p').after('<a href="#top">back to top</a>');
With .insertAfter(), we can continue acting on the created<a> element by chaining additional methods. With .after(), additional methods would act on the elements matched by the $('div.chapter p') selector instead.
So, now that we've actually inserted the links into the page (and into the DOM) after each paragraph that appears within<div class="chapter">, the back to top links will appear:
Unfortunately, the links won't work yet. We still need to insert the anchor with id="top". For this, we can use one of the methods that insert elements inside of other elements.
$(document).ready(function() {
$('<a href="#top">back to top</a>')
.insertAfter('div.chapter p');
$('<a id="top" name="top"></a>')
.prependTo('body');
});
This additional code inserts the anchor right at the beginning of the<body>; in other words, at the top of the page. Now, with the .insertAfter() method for the links and the .prependTo() method for the anchor, we have a fully functioning set of back to top links for the page.
With back to top
links, it doesn't make much sense to have them appear when the top of
the page is still visible. A quick improvement to the script would start
the links only after, say, the fourth paragraph. This is easy to
accomplish with a little change to the selector expression: .insertAfter('div.chapter p:gt(2)').
Why the 2 here? Remember that JavaScript indexing starts at 0;
therefore, the first paragraph is indexed as 0, the second is 1, the
third is 2, and the fourth paragraph is 3. Our selector expression
begins inserting the links after each paragraph when the index reaches
3, because that is the first one greater than 2.
The effect of this selector-expression change is now evident: